const fs = require('fs');
const argv = require('argv');
const chalk = require('chalk');
const chokidar = require('chokidar');
const exit = msg => {
    if(msg) {
        console.log(chalk.red('错误: ' + msg));
    }
    
    process.exit()
};

const format_bytes = (bytes, decimals) => {
    if (bytes === 0) {
        return '0 Bytes';
    }

    decimals = typeof decimals == 'undefined' ? 2 : decimals;
    
    const k = 1024;
    const dm = decimals < 0 ? 0 : decimals;
    const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
    const i = Math.floor(Math.log(bytes) / Math.log(k));
    return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
}

argv.info(
`用法: node md-compiler {source-path} [options]

必选参数:
        source-path: 编译源文件或者目录
        
可选参数:`
);

let footdoc = `
示例:

node md-compiler.js xxx

node md-compiler.js xxx --save=xxx/doc.html

高亮样式参数:

        a11y-dark
        a11y-light
        agate
        an-old-hope
        androidstudio
        arduino-light
        arta
        ascetic
        atelier-cave-dark
        atelier-cave-light
        atelier-dune-dark
        atelier-dune-light
        atelier-estuary-dark
        atelier-estuary-light
        atelier-forest-dark
        atelier-forest-light
        atelier-heath-dark
        atelier-heath-light
        atelier-lakeside-dark
        atelier-lakeside-light
        atelier-plateau-dark
        atelier-plateau-light
        atelier-savanna-dark
        atelier-savanna-light
        atelier-seaside-dark
        atelier-seaside-light
        atelier-sulphurpool-dark
        atelier-sulphurpool-light
        atom-one-dark
        atom-one-dark-reasonable
        atom-one-light
        brown-paper
        codepen-embed
        color-brewer
        darcula
        dark
        default
        docco
        dracula
        far
        foundation
        github
        github-gist
        gml
        googlecode
        gradient-dark
        gradient-light
        grayscale
        gruvbox-dark
        gruvbox-light
        hopscotch
        hybrid
        idea
        ir-black
        isbl-editor-dark
        isbl-editor-light
        kimbie.dark
        kimbie.light
        lightfair
        lioshi
        magula
        mono-blue
        monokai
        monokai-sublime
        night-owl
        nnfx
        nnfx-dark
        nord
        obsidian
        ocean
        paraiso-dark
        paraiso-light
        pojoaque
        purebasic
        qtcreator_dark
        qtcreator_light
        railscasts
        rainbow
        routeros
        school-book
        shades-of-purple
        solarized-dark
        solarized-light
        srcery
        stackoverflow-dark
        stackoverflow-light
        sunburst
        tomorrow
        tomorrow-night
        tomorrow-night-blue
        tomorrow-night-bright
        tomorrow-night-eighties
        vs
        vs2015
        xcode
        xt256
        zenburn
`;

let params = argv.option([
    {name: 'save', type:'string', description:'输出保存的位置'},
    {name: 'cssfile', type:'string', description:'添加额外的css文件'},
    {name: 'jsfile', type:'string', description: '添加额外的js文件'},
    {name: 'histyle', type:'string', description: '高亮样式'},
    {name: 'watch', type:'boolean', description: '监听模式'},
    {name: 'reserve-num-prefix', type:'boolean', description: '是否在目录中保留文件名的数字前缀'},
    {name: 'help', type:'boolean', description: '帮助文档'},
]).run();

if(params.options.help) {
    argv.help();
    console.log(footdoc);
    exit();
}

let format_date = function(date, format) {
    date = date || new Date();
    format = format || 'yyyy-MM-dd hh:mm:ss';
    return (function (fmt) {
        var o = {
            "M+": this.getMonth() + 1, //月份
            "d+": this.getDate(), //日
            "h+": this.getHours(), //小时
            "m+": this.getMinutes(), //分
            "s+": this.getSeconds(), //秒
            "q+": Math.floor((this.getMonth() + 3) / 3), //季度
            "S": this.getMilliseconds() //毫秒
        };
        if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
        for (var k in o)
            if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
        return fmt;
    }).call(date, format)
}

let source = null;

if(params.targets.length == 0) {
    exit('缺少构建源参数{source-path}');
}

source = params.targets[0];

const Compiler = require("./lib/compiler");

let compileTimer = null;
let begin_build = _ => {
    clearTimeout(compileTimer);
    compileTimer = setTimeout(_ => {
        let compiler = new Compiler;
        compiler.sourcePath = source != './' ? source.replace(/^\.[/\\]/, '') : source;
        compiler.saveTarget = params.options.save;
        compiler.histyle = params.options.histyle;
        compiler.cssfile = params.options.cssfile;
        compiler.jsfile = params.options.jsfile;
        compiler.reserveNumPrefix = params.options['reserve-num-prefix'];
        
        console.log("== 开始构建 "+source+" ==");
        let buildFile = compiler.build();
        console.log(chalk.gray('----------------------'));
        console.log("生成文件: " + chalk.green(buildFile));
        console.log("生成大小: " + format_bytes(fs.statSync(buildFile).size));
        console.log("版本: " + format_date() + "\n" );
    }, params.options.watch ? 300 : 1)
}

if(params.options.watch) {
    chokidar.watch(source).on('all', (e, path) => {
        if(['add', 'unlink', 'change'].includes(e)
            && /(\.md|\.jpg|\.png|\.bmp|\.gif|\.jpeg|[\\\/]sort|^sort)$/i.test(path)) {
            begin_build();
        }
    });
} else {
    begin_build();
}
